Skip to content

bpo-43224: Forbid TypeVar substitution with Unpack#32031

Merged
JelleZijlstra merged 1 commit into
python:mainfrom
serhiy-storchaka:typing-typevar-subst-unpack
Apr 13, 2022
Merged

bpo-43224: Forbid TypeVar substitution with Unpack#32031
JelleZijlstra merged 1 commit into
python:mainfrom
serhiy-storchaka:typing-typevar-subst-unpack

Conversation

@serhiy-storchaka

@serhiy-storchaka serhiy-storchaka commented Mar 21, 2022

Copy link
Copy Markdown
Member

Comment thread Lib/test/test_typing.py
for A in G, Tuple:
B = A[T, Unpack[Ts], str, T2]
with self.assertRaises(TypeError):
B[int, Unpack[Ts]]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remind me where PEP 646 forbids this? Assuming Unpack[Ts] === *Ts, it seems this is forbidding the following:

class G(Generic[*Ts]): ...
B = G[T, *Ts, str, T2]
X = B[int, *Ts]  # <-- TypeError here

What is wrong with X that isn't wrong with B?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll rewrite it as B[int, *Ts2], so we could unambiguously refer to variables.

AFAIK PEP 646 does not cover such case. It does not specify the result.

But what can be the result of substitution B[int, *Ts2]? T is substituted with int, T2 should be substituted with the last item of *Ts2, and *T should be substituted with all but the last items of *Ts2. But we cannot express this, because Ts2 is a variable. If we substitute *Ts2 with an empty sequence of types (X[()]), there would not be a value for T2.

I think that it is better to make it an error:

def f(a: tuple[*Ts2]) -> B[int, *Ts2]: ...

You should write

def f(a: tuple[*Ts2, T3]) -> B[int, *Ts2, T3]: ...

to make it having some sense.

There is a workaround of this problem. It may even make the code more clear. You can see, that a should be a tuple containing at least 1 item. T2 in B will be substituted with the type of the last item, and *Ts in B will be substituted with the rest of types.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrahtz what do you think of this case?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the prod, Jelle. I agree with Serhiy - looks like this is one of the cases we should forbid at runtime.

@JelleZijlstra JelleZijlstra left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good in principle, pending resolution of Guido's question.

@mrahtz mrahtz mannequin mentioned this pull request Apr 11, 2022
@JelleZijlstra JelleZijlstra merged commit 15537c5 into python:main Apr 13, 2022
@serhiy-storchaka serhiy-storchaka deleted the typing-typevar-subst-unpack branch July 1, 2026 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip news type-feature A feature request or enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants